import { FormItemConfig,getRandomKey } from './base.js'

class BaseComps {

  /**
 * @param { string } item  组件名称
 * @param {FormItemConfig} option  组件配置,将覆盖已有的配置
 * @returns {FormItemConfig}
 */
  static get(item,option = {}) {
    if (!this[item]) throw Error(`${item}  组件不存在`)
    // return Object.assign(this[item](),option)
    return _.merge(this[item](),option)

  }
  /**
  * @param {string[]} items  组件名称数组
  * @returns {FormItemConfig[]}
  */
  static getItems(items = []) {
    const result = []
    items.forEach(item => {
      if (this[item]) result.push(this[item]())
    })
    return result
  }




}


/**
 * 用于组件配置面板的配置项组件
 * 可快速配置 AllComps组件的configurableFieldItems
 */
class ConfigurableAttrFieldComps extends BaseComps {


  static suffix() {
    return new FormItemConfig({
      label: '后缀',key: 'attrs.suffix',compName: 'el-input',
    })
  }
  static title() {
    return new FormItemConfig({
      label: '标题',key: 'title',compName: 'el-input',
    })
  }
  static dataKey() {
    return new FormItemConfig({
      key: 'dataKey',
      label: '数据key',
      helpText: '保存数据时对应的key键',
      rules: [{ required: true,message: '必填项',trigger: 'change' }],
      compName: 'el-input',attrs: { type: 'text' },
    })
  }
  static label() {
    return new FormItemConfig({
      label: '标签',
      key: 'label',
      compName: 'el-input',attrs: { type: 'text','show-word-limit': true },
      rules: [{ required: true,message: '必填项',trigger: 'change' }],
    })
  }
  static placeholder() {
    return new FormItemConfig({
      label: 'placeholder',
      key: 'attrs.placeholder',
      compName: 'el-input',
      attrs: { type: 'text' }
    })
  }
  static icon() {
    return new FormItemConfig({
      key: 'icon',
      label: '图标',
      compName: 'el-input',attrs: { type: 'text',max: 10 }
    })
  }
  static readonly() {
    return new FormItemConfig({
      key: 'readonly',
      label: '只读',
      compName: 'el-switch',
    })

  }

  static required() {
    return new FormItemConfig({
      key: 'required',
      label: 'required',
      compName: 'el-switch'
    })
  }
  static span() {

    return new FormItemConfig({
      key: 'span',
      label: '栅格数',
      helpText: '栅格数',
      templateStr: `<el-radio-group v-model="_value">
         <el-radio-button v-for="(_,i) in $attrs.cols" :label="i+1" :key="i"></el-radio-button>
      </el-radio-group>`,
      attrs: { cols: 3 }
    })
  }

  static size() {
    return new FormItemConfig({
      helpText: '组件尺寸',
      label: '组件尺寸',key: 'attrs.size',
      templateStr: `<el-radio-group v-model="_value">
        <el-radio-button v-for="(item,i) in $attrs.sizeList" :label="item" :key="i"></el-radio-button>
      </el-radio-group>`,
      attrs: { sizeList: ['medium','small','mini'] }
    })
  }

  static dict() {
    /**  字典格式：[{ name: '字典1',code: [{ name: '字典1-1',code: '1' }] }] */
    const getDict = () => [{ name: '字典名1',code: [{ name: '字典1-1',code: '1' }] }];
    return AllComps.get('select',{ key: 'attrs.dict',configurable: false,label: '字典',attrs: { list: getDict() } })
  }

  static rules() {
    return new FormItemConfig({
      label: '校验规则(yaml)',
      helpText: `
      yaml数组格式如下:
       -
        required: true
        message: 测试必填
      -
        min: 3
        message: 最小长度3

  注意: 这会覆盖掉已设置的rules
`,
      key: 'rules',
      compName: 'x-attr-rules',
      rules: [{
        validator(rule,val,cb) {
          try {
            if (Array.isArray(val) && val.length) cb()
          } catch (error) {
            cb(new Error('JSON格式错误,输入数据json数组验证规则'))
          }
        }
      }]
    })

  }

  static hasBorder() {
    return new FormItemConfig({
      key: 'hasBorder',
      label: '显示边框',
      compName: 'el-switch'
    })
  }
}



/**
 *  CompBar 注册组件
 * 具备ConfigurableFields 配置项的信息
 */
class AllComps extends BaseComps {
  /**
   * 给   FormItemConfig.defaultConfigurableFields 的默认配置字段，添加ConfigurableAttrFieldComps 对应的comps
   * @param {FormItemConfig} comp 
   */
  static setDefaultConfigurableFieldItems(comp) {
    comp.configurableFieldItems = ConfigurableAttrFieldComps.getItems(comp.defaultConfigurableFields).concat(comp.configurableFieldItems)

  }

  /**
   * AllComps 中组件需要设置 configurableFieldItems ,也就是组件设置中可配置的表单控件，用来修改 AllComps 组件的属性
   * 此处重写父类BaseComps中get 和 getItems方法，用来设置 configurableFieldItems
   *@param {FormItemConfig} option 
    */
  static get(item,option) {
    const comp = super.get(item,option)
    if (comp.configurable) this.setDefaultConfigurableFieldItems(comp)
    else comp.configurableFieldItems = []
    return comp
  }
  static _get(item,option) {
    const comp = super.get(item,option)
    comp.configurableFieldItems = []
    comp.defaultConfigurableFields = []
    return comp
  }
  //***********************所有组件的注册**************************

  static emptyBlock() {
    return new FormItemConfig({
      title: '空白填充块',
      label: 'empty',
      templateStr: '<div></div>',
    })
  }

  static input() {
    return new FormItemConfig({
      title: '输入框',
      label: 'input',

      templateStr: `<el-input v-bind="$attrs"   v-model="_value">
      <template slot="append" v-if="$attrs.suffix">{{$attrs.suffix}}</template>
    </el-input>`,
      attrs: {
        size: 'mini',
        suffix: '',
        type: 'text',
        maxlength: 50,
        'show-word-limit': true
      },
      defaultConfigurableFields: ['size','placeholder','suffix'],
      configurableFieldItems: [
        new FormItemConfig({ compName: 'el-input',label: 'word-limit',key: 'attrs.maxlength',attrs: { type: 'number',min: 0 } }),
        new FormItemConfig({ compName: 'el-switch',label: 'show-word-limit',key: 'attrs.show-word-limit' }),
        this.get('select',{
          configurable: false,
          key: 'attrs.type',label: 'input框类型',
          attrs: {
            list: ['text','textarea','number','password','email','tel','url',
              'date','time','datetime-local',
              'month','week','color','file'].map(item => ({ name: item,code: item }))
          }
        })
      ],
    })
  }
  static select() {
    return new FormItemConfig({
      title: '下拉框',
      label: '下拉框',
      defaultConfigurableFields: ['dict'],
      templateStr: `<el-select v-model="_value" v-bind="$attrs">
        <el-option
          v-for= "(item,i) in ($attrs.dict?.length?$attrs.dict:$attrs.list)"
          :label="item.name" :key="i" :value="item.code">
        </el-option>
      </el-select>`,
      attrs: { list: [],multiple: false,clearable: true,dict: [],filterable: true,"allow-create": false },
      configurableFieldItems: [
        this.get('listEdit',{ key: 'attrs.list',label: '添加选项',configurable: false }),
        // this.get('switch',{ key: 'attrs.filterable',label: '可筛选' }),
        this.get('switch',{ configurable: false,key: 'attrs.allow-create',label: '可创建' }),

      ]

    })
  }

  static listEdit() {
    return new FormItemConfig({
      title: '列表编辑',
      label: '列表编辑',
      compName: Vue.extend({
        template: `
        <div>
          <div v-for="(item,index) in value" :key="index" style="display: flex;align-items: center;">
            <el-input   v-model="item.name" placeholder="key"></el-input>
            <el-input v-model="item.code" placeholder="val"></el-input>
            <el-button @click="del(index)" style="color: red;" type="text" size="mini">删除</el-button>
          </div>
            <el-button @click="add" type="default" size="mini" style="display: block; width: 100%;">增加</el-button>
        </div>
        `,
        props: { value: { default() { return [] } } },model: { event: 'change' },
        watch: { value: { handler(val) { this.$emit('change',val) },deep: true } },
        methods: { add() { this.value.push({ name: 'name',code: getRandomKey() }) },del(index) { this.value.splice(index,1) } }
      })
    })
  }
  static switch() {
    return new FormItemConfig({
      title: 'switch开关',
      compName: "el-switch",
      label: 'switch'
    })
  }
  static radioGroup() {
    return new FormItemConfig({
      title: 'radio框组',
      label: 'radio框组',

      defaultConfigurableFields: ['size','dict'],
      templateStr: `
        <el-radio-group v-model="_value" :size="$attrs.size">
        <component  :is="$attrs.isButton?'el-radio-button':'el-radio'" v-for= "(item,i) in ($attrs.dict?.length?$attrs.dict:$attrs.list)" :label="item.code" :key = "i" >
        {{item.name}}   </component >
        </el-radio-group> `,
      attrs: { list: [],isButton: false,size: 'mini',dict: [] },

      configurableFieldItems: [
        this.get('listEdit',{
          configurable: false,
          key: 'attrs.list',
          label: '添加radio选项',
          attrs: { list: [] }
        }),
        this.get('switch',{ configurable: false,key: 'attrs.isButton',label: '按钮样式' }),
      ]
    })
  }

  static iframe() {
    return new FormItemConfig({
      title: 'iframe',
      templateStr: `<iframe width="100%" height="500" :src="$attrs.src"></iframe>`,
      attrs: { src: 'http://127.0.0.1:5500/index.html' },
      configurableFieldItems: [
        new FormItemConfig({
          label: 'src',
          compName: 'el-input',
          key: 'attrs.src',
          attrs: { placeholder: '请输入iframe src' }
        })
      ]
    })
  }

  static blankTemplate() {
    return new FormItemConfig({
      label: '空白模板',
      title: '空白模板',
      configurableFieldItems: [
        new FormItemConfig({
          label: '组件名',
          compName: 'el-input',
          key: 'templateStr',
          attrs: { type: 'textarea',placeholder: '请输入 templateStr' }
        })
      ]
    })
  }


}
// console.log("AllComps.get('input')",AllComps.get('input'))
// console.log("AllComps.getItems(['input','select'])",AllComps.getItems(['input','select']))

export { AllComps,ConfigurableAttrFieldComps }

